// data.formatDD("yyyy-MM-DD hh:mm:ss");
Date.prototype.formatDD = function(formatStr){
	var date = this;
	var str = formatStr;
	str=str.replace(/yyyy|YYYY/,date.getFullYear());
	str=str.replace(/yy|YY/,(date.getYear() % 100)>9?(date.getYear() % 100).toString():"0" + (date.getYear() % 100));
	str=str.replace(/MM/,date.getMonth()>8?(date.getMonth()+1).toString():"0" + (date.getMonth()+1));
	str=str.replace(/M/g,date.getMonth()+1);
	str=str.replace(/dd|DD/,date.getDate()>9?date.getDate().toString():"0" + date.getDate());
	str=str.replace(/d|D/g,date.getDate());
	str=str.replace(/hh|HH/,date.getHours()>9?date.getHours().toString():"0" + date.getHours());
	str=str.replace(/h|H/g,date.getHours());
	str=str.replace(/mm/,date.getMinutes()>9?date.getMinutes().toString():"0" + date.getMinutes());
	str=str.replace(/m/g,date.getMinutes());
	str=str.replace(/ss|SS/,date.getSeconds()>9?date.getSeconds().toString():"0" + date.getSeconds());
	str=str.replace(/s|S/g,date.getSeconds());
	return str;
}

const zuiUtil = {
	//true  为模似数据   false  与后台交换
	mockFlag: false,
	utilName: {
		"tit": "公用utilJs中的内容zw，控制台还将会打印一些东西"
	},
	utilAlert () {
		console.log("公用util中的alert")
	},
	dom (id) {
		return document.getElementById(id);
	},
	domClass (searchClass,node,tag) {
		var classElements = new Array();
		if ( node == null )
			node = document;
		if ( tag == null )
			tag = '*';
		var els = node.getElementsByTagName(tag);
		var elsLen = els.length;
		var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
		for (var i = 0, j = 0; i < elsLen; i++) {
			if ( pattern.test(els[i].className) ) {
				classElements[j] = els[i];
				j++;
			}
		}
		return classElements;
	},
	hasClass: function(ele, cls) {
	  cls = cls || "";
	  if (cls.replace(/\s/g, "").length == 0) return false; //当cls没有参数时,返回false
	  return new RegExp(" " + cls + " ").test(" " + ele.className + " ");
	},
	addClass: function(ele, cls) {
	  if (!this.hasClass(ele, cls)) {
	    ele.className = ele.className == "" ? cls : ele.className + " " + cls;
	  }
	},
	removeClass: function(ele, cls) {
	  if (this.hasClass(ele, cls)) {
	    var newClass = " " + ele.className.replace(/[\t\r\n]/g, "") + " ";
	    while (newClass.indexOf(" " + cls + " ") >= 0) {
	      newClass = newClass.replace(" " + cls + " ", " ");
	    }
	    ele.className = newClass.replace(/^\s+|\s+$/g, "");
	  }
	},
	/**
	 * @param {HTMLElement} element
	 * @param {string} className
	 */
	toggleClass(element, className) {
	  if (!element || !className) {
	    return
	  }
	  let classString = element.className
	  const nameIndex = classString.indexOf(className)
	  if (nameIndex === -1) {
	    classString += '' + className
	  } else {
	    classString =
	      classString.substr(0, nameIndex) +
	      classString.substr(nameIndex + className.length)
	  }
	  element.className = classString
	},
	scrollToTop () {
		const c = document.documentElement.scrollTop || document.body.scrollTop;
		if (c > 0) {
		  window.requestAnimationFrame(scrollToTop);
		  window.scrollTo(0, c - c / 8);
		}
	},
	/** 返回当前页的滚动位置。**/
	getScrollPosition: (el = window) => ({x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft,
		y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop}),
	deepClone: function(origin, target) {
		if(target){
			// this.zutil.deepClone(b, a); -- 把a合并到b
			// 两个对象的合并
		  var target = target || {};
		  for (let prop in target) {
		    if (target.hasOwnProperty(prop)) {
		      if (target[prop] !== null && typeof target[prop] === 'object') {
		        origin[prop] = Object.prototype.toString.call(target[prop]) === '[object Array]' ? [] : {};
		        this.deepClone(origin[prop], target[prop]);
		      } else {
		        origin[prop] = target[prop];
		      }
		    }
		  }
		}else{
			// let c = this.zutil.deepClone(b); -- 把b复制给c
			// 对象的深拷贝
			if (typeof origin !== "object") return origin;
		  let newData = origin.constructor == Array ? [] : {};
		  const glob = typeof window === "undefined" ? global : window;
		  if (glob.JSON) {
		    /*使用JSON的方式实现拷贝*/
		    newData = JSON.parse(JSON.stringify(origin));
		  } else {
		    /*递归实现深拷贝*/
		    for (let i in origin) {
		      newData[i] = typeof origin[i] == 'object' ? this.deepClone(origin[i]) : origin[i];
		    }
		  }
		  return newData;
		}
	},
	zuiaccAdd: function(arg1,arg2){
		var r1,r2,m;
		try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
		try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
		m=Math.pow(10,Math.max(r1,r2))
		return (arg1*m+arg2*m)/m;
	},
	zuisubtr: function(arg1,arg2){
		var r1,r2,m,n;
		try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
		try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
		m=Math.pow(10,Math.max(r1,r2));
		n=(r1>=r2)?r1:r2;
		return Number(((arg1*m-arg2*m)/m).toFixed(n));
	},
	zuiaccMul: function(arg1,arg2) {
		var m=0,s1=arg1.toString(),s2=arg2.toString();
		try{m+=s1.split(".")[1].length}catch(e){}
		try{m+=s2.split(".")[1].length}catch(e){}
		return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m);
	},
	zuiaccDiv: function(arg1,arg2){
		if(arg2 == 0)
			return 0;
		var t1=0,t2=0,r1,r2;
		try{t1=arg1.toString().split(".")[1].length}catch(e){}
		try{t2=arg2.toString().split(".")[1].length}catch(e){}
		r1=Number(arg1.toString().replace(".",""));
		r2=Number(arg2.toString().replace(".",""));
		return (r1/r2)*Math.pow(10,t2-t1);
	},
	removeByIndex : function(arrays , dx){
		if(isNaN(dx)||dx>arrays.length){return false;}
		for(var i=0,n=0;i<arrays.length;i++){
			if(arrays[i]!=arrays[dx]){
				arrays[n++]=arrays[i]
			}
		}
		arrays.length-=1
		return arrays;
	},
	removeByValue : function(arrays, item ){
		for( var i = 0 ; i < arrays.length ; i++ ){
			if( item == arrays[i] ){
				break;
			}
		}
		if( i == arrays.length ){
			return;
		}
		for( var j = i ; j < arrays.length - 1 ; j++ ){
			arrays[ j ] = arrays[ j + 1 ];
		}
		arrays.length--;
		return arrays;
	},
	arrayLast: function(arrays){
		return arrays[arrays.length - 1];
	},
	getRandomArray: function(arr, count) {
		// 从一个数组中，随机取出count个元素组成新数组
	  var shuffled = arr.slice(0),
	    i = arr.length,
	    min = i - count,
	    temp, index;
	  while (i-- > min) {
	    index = Math.floor((i + 1) * Math.random());
	    temp = shuffled[index];
	    shuffled[index] = shuffled[i];
	    shuffled[i] = temp;
	  }
	  return shuffled.slice(min);
	},
	getCurDate(cDate, type){
		if(cDate && !(cDate instanceof Date))
			cDate = new Date(cDate);
		if(type && type == '2'){
			cDate = cDate.formatDD("yyyy-MM-DD hh:mm:ss");
		}else if(type){
			cDate = cDate.formatDD("yyyy-MM-DD hh:mm");
		}else{
			cDate = cDate.formatDD("yyyy-MM-DD");
		}
		return cDate;
	},
	lStorage: {
		setParam: function(name, value) {
			localStorage.setItem(name, value);
		},
		getParam: function(name) {
			return localStorage.getItem(name);
		},
		removeParam:function(name){
			localStorage.removeItem(name);
		},
		clearParam:function(){
			//清除所有的存储，谨慎使用
			localStorage.clear();
		}
	},
	closest: function(el, selector) {
		/**
		 * closest() 从元素本身开始，逐级向上级元素匹配，并返回最先匹配的祖先元素（包括自己本身）
		 * 它同parents()方法类似，不同点在于它只返回匹配的第一个元素节点。
		 * <div class="secwrap" @click="chooseSec($event, scope.row)">
        <el-button class="zbt secBtn" :class="{act: scope.row.level==index}" v-for="(item, index) in arr1" :key="index">{{item}}次</el-button>
      </div>
		 * chooseSec (ev) {
	      let e = ev || window.event;
	      let target = e.target || e.srcElement;
	      let _zparent = this.zutil.closest(target, '.secwrap');
	      let _zbtns = _zparent.querySelectorAll('.secBtn');
	    },
		**/
	  var matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
	  while (el) {
	    if (matchesSelector.call(el, selector)) {
	      break;
	    }
	    el = el.parentElement;
	  }
	  return el;
	},
	createUniqueString() {
	  const timestamp = +new Date() + ''
	  const randomNum = parseInt((1 + Math.random()) * 65536) + ''
	  return (+(randomNum + timestamp)).toString(32)
	},
	formatAxiosData: function(data) {
	  if (!this.mockFlag) {
	  	return data.data;
	  }else{
	  	return data.data;
	  }
	},
	hasOwn(obj, key) {
		return Object.prototype.hasOwnProperty.call(obj, key);
	},
	elementIsVisibleInViewport: (el, partiallyVisible = false) => {
		/**
		 * 如果指定的元素在视区中可见, 则返回true, 否则为false。
		 * 第二个参数指定true时允许只见部分，否则默认见到全部。
		 * 本方法只适用于元素高度不超过整屏高度的情况。
		 * elementIsVisibleInViewport(document.getElementById("test"))
		**/
	  const { top, left, bottom, right } = el.getBoundingClientRect();
	  return partiallyVisible ?
	    ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) &&
	    ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth)) :
	    top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
	},
	getURLParameters: (url = window.location.href) => {
		// getURLParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'}
		url.match(/([^?=&]+)(=([^&]*))/g).reduce((a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {})
	},
	ztype: {},
	_isType: function(type) {
	  if (!this.ztype[type]) {
	    this.ztype[type] = function(obj) {
	      return Object.prototype.toString.call(obj) === '[object ' + type + ']';
	    };
	  }
	  return this.ztype[type];
	},
	isArray: function(obj) {
	  return this._isType('Array')(obj);
	},
	isString: function(obj) {
	  return this._isType('String')(obj);
	},
	isBoolean: function(obj) {
	  return this._isType('Boolean')(obj);
	},
	isFunction: function(obj) {
	  return this._isType('Function')(obj);
	},
	isDate: function(obj) {
	  return this._isType('Date')(obj);
	},
	isNumber: function(obj) {
	  return this._isType('Number')(obj);
	},
	isNaN: function(obj) {
	  return obj !== obj;
	},
	isNull: function(obj) {
	  return obj === null;
	},
	isUndefined: function(obj) {
	  return obj === void 0;
	},
	isNumeric: function(obj) {
	  return obj - parseFloat(obj) >= 0;
	},
	isPlainObject: function(obj) {
	  return obj && typeof obj === "object" && Object.getPrototypeOf(obj) === Object.prototype;
	},
	isEmpty: function(obj) {
		// false\true是否需要判断？
	  return this.isNull(obj) || this.isUndefined(obj) || this.isString(obj) && obj === "";
	},
	separator: function(num) {
		/*给数字增加千位分隔符*/
	  var res = null;
	  if (this.isNaN(Number(num))) {
	    res = '非数字';
	  } else {
	    res = num.toString().replace(/\d+/, function(n) {
	      return n.replace(/(\d)(?=(\d{3})+$)/g, function($1) {
	        return $1 + ",";
	      });
	    })
	  }
	  return res;
	},
	trim: function(str) {
		// 去除字符串两边的空格
	  if (!this.isString(str)) {
	    str = String(str);
	  }
	  if (this.isFunction(String.prototype.trim)) {
	    return String.prototype.trim.call(str);
	  } else {
	    return str.replace(/(^\s*)|(\s*$)/g, '');
	  }
	},
	clearNoNumLastDot: function (obj) {
		if (obj.value.indexOf(".") == obj.value.toString().length-1) {
			// 去除.结尾的情况
			obj.value = parseFloat(obj.value);
		}
	},
	clearNoNum: function (obj, type) {
		// <input class="weui-input J_COD" type="text" placeholder="请输入PAM(kg)" onkeyup='clearNoNum(this)' onblur='clearNoNum(this)'>
		// <el-input class="zinput" v-model="tempPatienInfo.cheight" @keyup.native='clearNoNum($event, 1)'></el-input>
	  if (type) {
	    obj.value = obj.value.replace(/[^\d.]/g, ""); //清除“数字”和“.”以外的字符
	    obj.value = obj.value.replace(/\.{2,}/g, "."); //只保留第一个. 清除多余的
	    obj.value = obj.value.replace(".", "$#$").replace(/\./g, "").replace("$#$", ".");
	    if (type == '1') {
	      obj.value = obj.value.replace(/^(\-)*(\d+)\.(\d).*$/, '$1$2.$3'); //只能输入一位小数
	    } else if (type == '2') {
	      obj.value = obj.value.replace(/^(\-)*(\d+)\.(\d{2}).*$/, '$1$2.$3'); //只能输入两个小数
	    } else if (type == '3') {
	      obj.value = obj.value.replace(/^(\-)*(\d+)\.(\d{3}).*$/, '$1$2.$3'); //只能输入三位小数
	    }
	    //以上已经过滤，此处控制的是如果没有小数点，首位不能为类似于 01、02的金额
	    if (obj.value.indexOf(".") < 0 && obj.value != "") {
	      obj.value = parseFloat(obj.value);
	    }
	    //控制.开头的数字，如：.8798321
	    // \.16513000.546
	    if (obj.value && !obj.value.split(".")[0]) {
	      obj.value = '0.' + (obj.value.split(".")[1] || '');
	      this.clearNoNum(obj);
	    }
	    if (!obj.value)
	      obj.value = 0;
	  } else {
	    // 限制输入正整数
	    obj.value = obj.value.replace(/[^\d]/g, "");
	  }
	},
	getDomStyle () {
		// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
		// let styL = getDomStyle(dragDom, 'left');
		if (window.document.currentStyle) {
			return (dom, attr) => dom.currentStyle[attr];
		} else{
			return (dom, attr) => getComputedStyle(dom, false)[attr];
		}
	},
	zalgorithm: function (min, max, val, interv) {
		return Math.round(this.zuiaccAdd(this.zuiaccDiv(this.zuisubtr(val, min), this.zuisubtr(max, min)), interv) * 100) / 100;
		// return Math.round(((val - min) / (max - min) + interv)*100)/100;
	},
	visualData: function (val) {
		if(!val)
			return '';
		/**
		 * 将真实数据转换成虚拟值
		**/
		val = parseFloat(val);
		if(0 < val && val <= 2) {
      val = this.zalgorithm(0, 2, val, 0);
		}else if(2 < val && val <= 3.9){
			val = this.zalgorithm(2, 3.9, val, 1);
		}else if(3.9 < val && val <= 5.2){
			val = this.zalgorithm(3.9, 5.2, val, 2);
		}else if(5.2 < val && val <= 6.5){
			val = this.zalgorithm(5.2, 6.5, val, 3);
		}else if(6.5 < val && val <= 7.8){
			val = this.zalgorithm(6.5, 7.8, val, 4);
		}else if(7.8 < val && val <= 12){
			val = this.zalgorithm(7.8, 12, val, 5);
		}else if(12 < val && val <= 25){
			val = this.zalgorithm(12, 25, val, 6);
		}
		return val;
	},
	zalgorithmS: function (min, max, val, interv) {
		return Math.round(this.zuiaccAdd(this.zuiaccMul(this.zuisubtr(val, interv), this.zuisubtr(max, min)), max) * 100) / 100;
		// return Math.round(((val - interv) * (max - min) + max)*100)/100;
	},
	ztrueData: function (val) {
		if(!val)
			return '';
		/**
		 * 将虚拟值转换成真实数据
		**/
		val = parseFloat(val);
		if(0 < val && val <= 1) {
      val = this.zalgorithmS(0, 2, val, 1);
		}else if(1 < val && val <= 2) {
      val = this.zalgorithmS(2, 3.9, val, 2);
		}else if(2 < val && val <= 3) {
      val = this.zalgorithmS(3.9, 5.2, val, 3);
		}else if(3 < val && val <= 4) {
      val = this.zalgorithmS(5.2, 6.5, val, 4);
		}else if(4 < val && val <= 5) {
      val = this.zalgorithmS(6.5, 7.8, val, 5);
		}else if(5 < val && val <= 6) {
      val = this.zalgorithmS(7.8, 12, val, 6);
		}else if(6 < val && val <= 7) {
      val = this.zalgorithmS(12, 25, val, 7);
		}
		return val;
	},
	zgetConRange: function () {
		let data = this.lStorage.getParam("w_ConRange");
		if(data)
			data = JSON.parse(data);
		return [0, data.aftermeal.min, data.aftermeal.max, data.fasting.min, data.fasting.max, 11.1, 33];
	},
	zsetConRange: function (val) {
		// {aftermeal: {min: 3.9, max: 7.8 }, fasting: {min: 3.9, max: 6.1 } }
		this.lStorage.setParam("w_ConRange", JSON.stringify(val));
	},
	getlistHeight: function (val, min) {
		const _h = document.documentElement.clientHeight;
		let _val = _h - val;
		_val = _val<min ? min : _val;
		return _val+'px';
	},
	findParents (array, id) {
		// 树形结构根据id查找所有父节点
	  let stack = [];
	  let going = true;
	  let walker = (array, id) => {
	    array.forEach(item => {
	      if (!going) return;
	      stack.push(item.id);
	      if (item.id === id) {
	        going = false;
	      } else if (item['children']) {
	        walker(item['children'], id);
	      } else {
	        stack.pop();
	      }
	    });
	    if (going) stack.pop();
	  }
	  walker(array, id);
	  return stack;
	},
	breadthQuery(id, tree) {
		// 树形结构，根据id查找当前对象
	  var stark = [];
	  stark = stark.concat(tree);
	  while(stark.length) {
	    var temp = stark.shift();
	    if(temp.children) {
	      stark = stark.concat(temp.children);
	    }
	    if(temp.id === id) {
	      return temp;
	    }
	  }
	  return false;
	},
	cssRulesAdd: function (css) {
		const target = document.head || document.body || document.documentElement;
		const style = document.createElement('style');
		style.textContent = css;
		let removed = false;
		let ready = Promise.resolve();
		if (target) target.appendChild(style);
		else {
		  ready = new Promise(resolve => {
		    setTimeout(function addStyle() {
		      if (removed) {
		        resolve();
		        return;
		      }
		      const target = document.head || document.body || document.documentElement;
		      if (!target) setTimeout(addStyle, 10);
		      else {
		        target.appendChild(style);
		        resolve();
		      }
		    }, 10);
		  });
		}
		const remove = () => {
		  if (!style.parentNode) return;
		  style.parentNode.removeChild(style);
		  removed = true;
		};
		const append = css => {
		  style.textContent += '\n' + css;
		};
		return { append, remove, ready };
	},
	_cssRulesObj: null,
	_cssRulesObjFunc: function () {
		if(!this._cssRulesObj){
			this._cssRulesObj = this.cssRulesAdd('');
		}
		return this._cssRulesObj;
	},
	cssRulesAppend: function (css) {
		let _obj = this._cssRulesObjFunc();
		_obj.append('\n' + css);
	},
	convertImgToBase64: function (url, callback, outputFormat) {
	  var canvas = document.createElement('canvas');
	  var ctx = canvas.getContext('2d');
	  var img = new Image;
	  img.crossOrigin = 'Anonymous';
	  img.onload = function() {
	    canvas.height = img.height;
	    canvas.width = img.width;
	    ctx.drawImage(img, 0, 0);
	    var dataURL = canvas.toDataURL(outputFormat || 'image/png');
	    callback.call(this, dataURL);
	    // Clean up
	    canvas = null;
	  };
	  img.src = url;
	},
	getQueryString(name) {
	  var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
	  var url = decodeURI(window.location);
	  var r = window.location.search.substr(1).match(reg);
	  if (r != null)
	    return unescape(r[2]);
	  return null;
	},
	initBtnsClickEvent (that, curObj, func) {
		/**
		 * 修正cube-ui滚动插件在微信开发者工具中无法点击问题
		 * this.zutil.initBtnsClickEvent(this, '.zuiReplayBtn', this.zreplay);
		**/
    that.$nextTick(()=>{
    	let _objs = document.querySelectorAll(curObj);
    	if(_objs && _objs.length){
    		_objs.forEach(v=>{
	      	v.removeEventListener('tap', func);
	        v.addEventListener('tap', func, true);
	      })
    	}
    })
	}
}

Number.prototype.add = function (arg) {
  return zuiUtil.zuiaccAdd(this, arg);
}
Number.prototype.sub = function (arg) {
  return zuiUtil.zuisubtr(this, arg);
}
Number.prototype.mul = function (arg) {
  return zuiUtil.zuiaccMul(this, arg);
}
Number.prototype.div = function (arg) {
  return zuiUtil.zuiaccDiv(this, arg);
}
// console.log((9).div(3).mul(2).add(2).sub(11).add(2))

export default zuiUtil;
